﻿using BootstrapBlazor.Components;
using BPM.Web.Shared.Data;
using WebApiClientCore;
using WebApiClientCore.Exceptions;

namespace BPM.Web.Shared.Service;

/// <summary>
/// 业务方法封装
/// </summary>
public abstract class BaseService
{
    protected readonly ToastService Toast;

    public BaseService(ToastService toast) => Toast = toast;

    /// <summary>
    /// 分页查询
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="task"></param>
    /// <returns></returns>
    protected async Task<QueryData<T>> QueryAsync<T>(ITask<XnRestfulResult<PageResult<T>>> task) where T : class, new()
    {
        var result = new QueryData<T>();
        try
        {
            var data = await task;
            if (data.Success)
            {
                result.Items = data.Data?.Rows ?? Enumerable.Empty<T>();
                result.TotalCount = data.Data?.TotalRows ?? 0;
            }
            else await Toast.Error(data.GetCode(), data.GetMessage());
        }
        catch (ApiResponseStatusException ex)
        {
            await Toast.Error(((int)ex.StatusCode).ToString(), ex.Message);
        }
        catch (Exception ex)
        {
            await Toast.Error("500", ex.Message);
        }
        return result;
    }

    /// <summary>
    /// 查询结果
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="task"></param>
    /// <returns></returns>
    protected async Task<QueryData<T>> QueryAsync<T>(ITask<XnRestfulResult<List<T>>> task) where T : class, new()
    {
        var result = new QueryData<T>();
        var data = await task;
        if (data.Success)
        {
            result.Items = data.Data ?? Enumerable.Empty<T>();
            result.TotalCount = data.Data?.Count ?? 0;
        }
        else await Toast.Error(data.GetCode(), data.GetMessage());
        return result;
    }

    /// <summary>
    /// 查询结果
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="task"></param>
    /// <returns></returns>
    protected async Task<T?> QueryAsync<T>(ITask<XnRestfulResult<T>> task) where T : class, new()
    {
        var result = default(T);
        var data = await task;
        if (data.Success)
        {
            return data.Data;
        }
        else await Toast.Error(data.GetCode(), data.GetMessage());

        return result;
    }

    /// <summary>
    /// 删除操作
    /// </summary>
    /// <param name="tasks"></param>
    /// <returns></returns>
    protected async Task<bool> DeleteAsync(IEnumerable<ITask<XnRestfulResult<string>>> tasks)
    {
        var result = new List<XnRestfulResult<string>>();
        foreach (var task in tasks)
        {
            result.Add(await task);
        }

        if (result.Count == 0)
        {
            await Toast.Error("500", "操作失败，没有删除数据。");
            return false;
        }
        else if (result.Count == 1)
        {
            if (!result[0].Success)
            {
                await Toast.Error(result[0].GetCode(), result[0].GetMessage());
            }
            return result[0].Success;
        }
        else
        {
            foreach (var item in result)
            {
                if (!item.Success)
                {
                    await Toast.Error(item.GetCode(), item.GetMessage() ?? "删除失败。");
                }
            }
            return true;
        }
    }

    /// <summary>
    /// 执行操作
    /// </summary>
    /// <param name="task"></param>
    /// <param name="type"></param>
    /// <returns></returns>
    protected async Task<bool> ExecuteAsync(ITask<XnRestfulResult<string>> task, ItemChangedType? type = null)
    {
        var result = await task;
        var method = "操作";
        switch (type)
        {
            case ItemChangedType.Add: method = "新增"; break;
            case ItemChangedType.Update: method = "更新"; break;
        }
        if (!result.Success)
        {
            await Toast.Error(result.GetCode(), result.GetMessage() ?? $"{method}失败。");
        }

        return result.Success;
    }

    /// <summary>
    /// 执行操作
    /// </summary>
    /// <param name="task"></param>
    /// <param name="type"></param>
    /// <returns></returns>
    protected async Task<TResult?> ExecuteAsync<TResult>(ITask<XnRestfulResult<TResult>> task, ItemChangedType? type = null)
    {
        var result = await task;
        var method = "操作";
        switch (type)
        {
            case ItemChangedType.Add: method = "新增"; break;
            case ItemChangedType.Update: method = "更新"; break;
        }
        if (!result.Success)
        {
            await Toast.Error(result.GetCode(), result.GetMessage() ?? $"{method}失败。");
        }

        return result.Data;
    }
}

